Spring Security-তে Authentication (প্রমাণীকরণ) এবং Authorization (অনুমোদন) হলো এর দুটি প্রধান কার্যক্রম।
1. Authentication (প্রমাণীকরণ):
Authentication হচ্ছে ব্যবহারকারীর পরিচয় যাচাই করার প্রক্রিয়া। এটি নিশ্চিত করে যে ব্যবহারকারী আসলেই কে সে দাবি করছে।
Authentication এর গুরুত্বপূর্ণ বিষয়গুলো:
- User Credentials: যেমন: ব্যবহারকারীর নাম এবং পাসওয়ার্ড।
- Authentication Manager: ব্যবহারকারীর তথ্য যাচাই করে।
- Authentication Provider: তথ্য যাচাই করার জন্য বাস্তবায়ন (e.g., In-Memory, Database, LDAP)।
Spring Security-তে Authentication বাস্তবায়ন:
1. In-Memory Authentication:
Spring Security ডেভেলপমেন্টে সহজ টেস্টিংয়ের জন্য In-Memory Authentication ব্যবহার করা হয়।
উদাহরণ:
@Configuration
public class SecurityConfig {
@Bean
public InMemoryUserDetailsManager userDetailsManager() {
UserDetails user = User.withUsername("user")
.password(passwordEncoder().encode("password"))
.roles("USER")
.build();
UserDetails admin = User.withUsername("admin")
.password(passwordEncoder().encode("admin"))
.roles("ADMIN")
.build();
return new InMemoryUserDetailsManager(user, admin);
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
2. Database Authentication:
ব্যবহারকারীর তথ্য ডাটাবেসে সংরক্ষণ করা হলে এই পদ্ধতি ব্যবহৃত হয়।
উদাহরণ:
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication()
.dataSource(dataSource)
.usersByUsernameQuery("SELECT username, password, enabled FROM users WHERE username = ?")
.authoritiesByUsernameQuery("SELECT username, authority FROM authorities WHERE username = ?");
}
3. LDAP Authentication:
LDAP (Lightweight Directory Access Protocol) এর মাধ্যমে Authentication করার জন্য Spring Security ব্যবহার করা যায়।
2. Authorization (অনুমোদন):
Authorization নিশ্চিত করে যে নির্দিষ্ট ব্যবহারকারী কোন রিসোর্স অ্যাক্সেস করতে পারবেন এবং কীভাবে ব্যবহার করবেন।
Authorization এর মূল উপাদান:
- Roles (ভূমিকা): উদাহরণ:
ROLE_USER,ROLE_ADMIN - Authorities: নির্দিষ্ট কাজের অনুমতি, উদাহরণ:
READ_PRIVILEGES,WRITE_PRIVILEGES - Access Control: কোন ব্যবহারকারী কোন রিসোর্সে প্রবেশাধিকার পাবে তা নির্ধারণ।
Spring Security-তে Authorization বাস্তবায়ন:
1. HTTP Authorization:
Spring Security-তে URL প্যাটার্ন ভিত্তিক Authorization সেটআপ করা যায়।
উদাহরণ:
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/admin/**").hasRole("ADMIN")
.requestMatchers("/user/**").hasAnyRole("USER", "ADMIN")
.anyRequest().authenticated()
)
.formLogin()
.and()
.logout().permitAll();
return http.build();
}
2. Method-Level Authorization:
স্প্রিং সিকিউরিটি অ্যানোটেশন ব্যবহার করে মেথড-লেভেল Authorization সেটআপ করা যায়।
উদাহরণ:
- @PreAuthorize:
@PreAuthorize("hasRole('ADMIN')")
public void adminOnlyFunction() {
// Admin specific operation
}
- @PostAuthorize:
@PostAuthorize("returnObject.username == authentication.name")
public User getUserById(Long id) {
return userService.findById(id);
}
- @Secured:
@Secured("ROLE_ADMIN")
public void securedFunction() {
// Admin specific operation
}
3. Role Hierarchy:
Role Hierarchy ব্যবহার করে রোলগুলোর মধ্যে সম্পর্ক নির্ধারণ করা যায়।
উদাহরণ:
@Bean
public RoleHierarchy roleHierarchy() {
RoleHierarchyImpl hierarchy = new RoleHierarchyImpl();
hierarchy.setHierarchy("ROLE_ADMIN > ROLE_MANAGER > ROLE_USER");
return hierarchy;
}
Authentication এবং Authorization এর প্রক্রিয়া:
- Authentication Flow:
- ব্যবহারকারী লগইন করলে তাদের Credentials (e.g., username এবং password)
AuthenticationManager-এ পাঠানো হয়। AuthenticationProviderCredentials যাচাই করে।- যাচাই সফল হলে একটি
Authenticationঅবজেক্ট তৈরি হয় এবংSecurityContext-এ সেট করা হয়।
- ব্যবহারকারী লগইন করলে তাদের Credentials (e.g., username এবং password)
- Authorization Flow:
SecurityContext-এরAuthenticationঅবজেক্ট থেকে ব্যবহারকারীর রোল এবং অথরিটিস চেক করা হয়।- সিস্টেম নির্ধারিত নীতিমালা অনুযায়ী রিসোর্স অ্যাক্সেস প্রদান বা নিষিদ্ধ করা হয়।
JWT এবং Authentication:
Spring Security-তে JWT (JSON Web Token) ব্যবহার করে Authentication বাস্তবায়ন করা যায়।
উদাহরণ:
http.csrf().disable()
.authorizeHttpRequests(auth -> auth
.requestMatchers("/login").permitAll()
.anyRequest().authenticated()
)
.addFilter(new JWTAuthenticationFilter(authenticationManager()))
.addFilter(new JWTAuthorizationFilter(authenticationManager()));
উপসংহার:
Spring Security এর Authentication এবং Authorization সহজে কাস্টমাইজ এবং ইন্টিগ্রেট করা যায়। এটি ব্যবহার করে ডেভেলপাররা নিরাপদ এবং স্কেলযোগ্য অ্যাপ্লিকেশন তৈরি করতে পারেন।
- Authentication: ব্যবহারকারীর পরিচয় যাচাই করে।
- Authorization: ব্যবহারকারীর অ্যাক্সেস নিয়ন্ত্রণ করে।
এটি স্প্রিং বুটের সাথে একত্রিত হয়ে REST API এবং ওয়েব অ্যাপ্লিকেশনের নিরাপত্তা নিশ্চিত করে।
Authentication বা প্রমাণীকরণ হল সেই প্রক্রিয়া যার মাধ্যমে ব্যবহারকারীর পরিচয় যাচাই করা হয়। Spring Security এর Authentication মডিউল একটি অ্যাপ্লিকেশন বা সিস্টেমে প্রবেশের জন্য ব্যবহারকারীর ইউজারনেম এবং পাসওয়ার্ড বা অন্য যেকোনো তথ্য যাচাই করতে ব্যবহৃত হয়। এটি নিরাপত্তা ব্যবস্থার প্রথম ধাপ এবং অত্যন্ত গুরুত্বপূর্ণ।
Authentication এর ভূমিকা:
- ব্যবহারকারী পরিচয় যাচাই:
- নিশ্চিত করে যে ব্যবহারকারী বৈধ এবং সঠিক পরিচয় প্রদান করছে।
- এটি পাসওয়ার্ড, টোকেন, বা অন্যান্য প্রমাণীকরণ পদ্ধতির মাধ্যমে করা হয়।
- সিস্টেম সুরক্ষা নিশ্চিত করা:
- শুধুমাত্র অনুমোদিত ব্যবহারকারীরা সিস্টেমে অ্যাক্সেস পায়।
- Unauthorized অ্যাক্সেস প্রতিরোধ করে।
- সঠিক রিসোর্স অ্যাক্সেস নিয়ন্ত্রণ:
- Authentication নিশ্চিত করে যে ব্যবহারকারীর নির্দিষ্ট রিসোর্স অ্যাক্সেস করার বৈধতা রয়েছে।
- ব্যবহারকারীর জন্য কাস্টমাইজড অভিজ্ঞতা:
- Authentication এর মাধ্যমে সিস্টেম ব্যবহারকারীর প্রোফাইল বা রোল অনুযায়ী রিসোর্স এবং ফিচার সরবরাহ করতে পারে।
- SecurityContext তৈরি করা:
- Authentication সফল হলে ব্যবহারকারীর তথ্য SecurityContext এ সংরক্ষণ করা হয়, যা অ্যাপ্লিকেশন জুড়ে ব্যবহার করা যায়।
Spring Security এর Authentication Component:
- AuthenticationManager:
- Authentication পরিচালনার মূল উপাদান।
- এটি Spring Security এর কোর ইন্টারফেস যা ব্যবহারকারীর প্রমাণীকরণ পরিচালনা করে।
- AuthenticationProvider:
- AuthenticationManager কে ব্যবহারকারীর তথ্য যাচাই করার জন্য সহায়তা করে।
- বিভিন্ন Authentication পদ্ধতি (যেমন, পাসওয়ার্ড, টোকেন) সাপোর্ট করে।
- UserDetailsService:
- ডেটাবেস বা অন্য ডেটা সোর্স থেকে ব্যবহারকারীর তথ্য লোড করে।
- এটি ব্যবহারকারীর ইউজারনেম, পাসওয়ার্ড, এবং রোল প্রদান করে।
- SecurityContextHolder:
- Authentication সফল হলে ব্যবহারকারীর তথ্য SecurityContextHolder এ সংরক্ষিত হয়।
- এটি অ্যাপ্লিকেশন জুড়ে ব্যবহার করা যায়।
- Authentication Token:
- ব্যবহারকারীর প্রমাণীকরণের তথ্য (যেমন, ইউজারনেম এবং পাসওয়ার্ড) ধরে রাখে।
- যেমন: UsernamePasswordAuthenticationToken।
Spring Security Authentication এর কাজের ধাপ:
- ব্যবহারকারী লগইন রিকোয়েস্ট করে।
- Spring Security ফিল্টার চেইন লগইন রিকোয়েস্ট ক্যাপচার করে।
- AuthenticationManager এবং AuthenticationProvider ব্যবহার করে ব্যবহারকারীর পরিচয় যাচাই করে।
- যদি Authentication সফল হয়:
- SecurityContextHolder এ ব্যবহারকারীর ডিটেইল সংরক্ষণ করা হয়।
- ব্যবহারকারী নির্দিষ্ট রিসোর্স বা পেজে পুনঃনির্দেশিত হয়।
- যদি Authentication ব্যর্থ হয়:
- ব্যবহারকারীকে ব্যর্থতার বার্তা দেখানো হয় বা অ্যাক্সেস প্রত্যাখ্যান করা হয়।
Authentication উদাহরণ:
১. In-Memory Authentication:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user").password("{noop}password").roles("USER")
.and()
.withUser("admin").password("{noop}admin").roles("ADMIN");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.httpBasic();
}
}
এখানে
{noop}নির্দেশ করে পাসওয়ার্ড এনকোডিং নেই। প্রোডাকশনে BCryptEncoder ব্যবহার করা উচিত।
২. Database-Driven Authentication (JPA):
@Service
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByUsername(username);
if (user == null) {
throw new UsernameNotFoundException("User not found");
}
return new org.springframework.security.core.userdetails.User(
user.getUsername(),
user.getPassword(),
Collections.singletonList(new SimpleGrantedAuthority("ROLE_USER"))
);
}
}
JWT ভিত্তিক Authentication উদাহরণ:
Authentication Filter:
public class JwtAuthenticationFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
String token = request.getHeader("Authorization");
if (token != null && token.startsWith("Bearer ")) {
token = token.substring(7);
// Validate and extract user information from the token
String username = JwtUtil.extractUsername(token);
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
// Set the authentication
UsernamePasswordAuthenticationToken authentication =
new UsernamePasswordAuthenticationToken(username, null, new ArrayList<>());
SecurityContextHolder.getContext().setAuthentication(authentication);
}
}
filterChain.doFilter(request, response);
}
}
Authentication এর সুবিধা:
- Unauthorized Access প্রতিরোধ:
- শুধুমাত্র বৈধ ব্যবহারকারীদের অ্যাক্সেস নিশ্চিত করে।
- নিরাপত্তা জোরদার:
- তথ্য চুরি বা অবৈধ অ্যাক্সেস প্রতিরোধ করে।
- ব্যবহারকারীর নির্ভরযোগ্যতা বৃদ্ধি:
- ব্যবহারকারীরা জানে যে তাদের তথ্য সুরক্ষিত।
Spring Security এর Authentication মডিউল একটি শক্তিশালী নিরাপত্তা ব্যবস্থা প্রদান করে যা এন্টারপ্রাইজ এবং ওয়েব অ্যাপ্লিকেশনকে সুরক্ষিত করে।
Authorization হল সেই প্রক্রিয়া যার মাধ্যমে নিশ্চিত করা হয় যে কোন ব্যবহারকারী কোন রিসোর্স বা অ্যাকশনে অ্যাক্সেস করার অনুমতি পাবে। এটি Spring Security-এর একটি গুরুত্বপূর্ণ দিক।
Spring Security Authorization মূলত Authentication-এর পরে কাজ করে। যখন ব্যবহারকারী সঠিকভাবে authenticate হয়, তখন তার role বা permission যাচাই করে সিদ্ধান্ত নেওয়া হয় যে সে নির্দিষ্ট রিসোর্স অ্যাক্সেস করতে পারবে কি না।
Authorization এর কাজ করার ধাপ
- Authentication (ব্যবহারকারী সঠিক কিনা তা যাচাই):
ব্যবহারকারীর পরিচয় যাচাই করা হয় (যেমন ইউজারনেম এবং পাসওয়ার্ড)। - Authorization (ব্যবহারকারীর অধিকার যাচাই):
যাচাই করা হয় যে ব্যবহারকারী কোন রিসোর্সে প্রবেশ করতে পারবে এবং কী অ্যাকশন (যেমন read/write/delete) করতে পারবে।
Spring Security-তে Authorization এর উপায়
Spring Security-তে Authorization কয়েকটি পদ্ধতিতে করা যায়:
1. URL-Based Authorization
- এই পদ্ধতিতে নির্দিষ্ট URL বা endpoint-এর জন্য অ্যাক্সেস নিয়ন্ত্রণ প্রয়োগ করা হয়।
উদাহরণ:
@Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/admin/**").hasRole("ADMIN") // শুধুমাত্র ADMIN রোল অ্যাক্সেস পাবে .antMatchers("/user/**").hasAnyRole("USER", "ADMIN") // USER বা ADMIN রোল পাবে .antMatchers("/public/**").permitAll() // সবাই অ্যাক্সেস পাবে .anyRequest().authenticated() // অন্যসব রিসোর্সের জন্য authentication প্রয়োজন .and() .formLogin(); }
2. Role-Based Authorization
- এই পদ্ধতিতে ব্যবহারকারীর নির্দিষ্ট role (যেমন:
ADMIN,USER) এর উপর ভিত্তি করে authorization নিয়ন্ত্রণ করা হয়। উদাহরণ:
@PreAuthorize("hasRole('ADMIN')") public String adminAccess() { return "This is an admin-only resource."; }
3. Method-Level Authorization
- Spring Security এর মাধ্যমে মেথড-লেভেলে authorization নিয়ন্ত্রণ করা যায়।
- এটি সাধারণত
@PreAuthorize,@PostAuthorize,@Securedবা@RolesAllowedঅ্যানোটেশন ব্যবহার করে করা হয়। উদাহরণ:
@Service public class MyService { @PreAuthorize("hasRole('ADMIN')") public void performAdminTask() { // শুধুমাত্র ADMIN রোল সম্পন্ন করতে পারবে } @PreAuthorize("hasAuthority('READ_PRIVILEGE')") public void readData() { // নির্দিষ্ট প্রিভিলেজ যাচাই } }
4. Custom Authorization
- Custom logic লিখে authorization নিয়ন্ত্রণ করা যায়।
উদাহরণ:
@Component("customPermissionEvaluator") public class CustomPermissionEvaluator implements PermissionEvaluator { @Override public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) { // Custom logic return true; // বা false } @Override public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Object permission) { // Custom logic return true; // বা false } }
5. Access Control Expressions
- Spring Security একটি শক্তিশালী Access Control Expressions সাপোর্ট করে।
উদাহরণ:
@Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/api/**").access("hasRole('USER') and hasIpAddress('192.168.1.0/24')") .anyRequest().authenticated(); }
Authorization এর প্রকারভেদ
Spring Security-তে Authorization বিভিন্নভাবে করা যায়। এর প্রকারভেদ হলো:
1. Role-Based Access Control (RBAC):
- RBAC সিস্টেমে, ব্যবহারকারীর একটি নির্দিষ্ট role থাকে। রোল অনুযায়ী ব্যবহারকারীকে রিসোর্সে অ্যাক্সেস দেওয়া হয়।
উদাহরণ:
http.authorizeRequests() .antMatchers("/admin/**").hasRole("ADMIN") .antMatchers("/user/**").hasAnyRole("USER", "ADMIN");
2. Attribute-Based Access Control (ABAC):
- এই পদ্ধতিতে নির্দিষ্ট অ্যাট্রিবিউট বা প্রোপার্টির উপর ভিত্তি করে অ্যাক্সেস নিয়ন্ত্রণ করা হয়।
উদাহরণ:
@PreAuthorize("#user.username == authentication.name") public void updateUserProfile(User user) { // শুধুমাত্র ব্যবহারকারী নিজের প্রোফাইল আপডেট করতে পারবে }
3. Permission-Based Access Control:
- এখানে Role-এর পরিবর্তে নির্দিষ্ট permission (যেমন:
READ_PRIVILEGE,WRITE_PRIVILEGE) যাচাই করা হয়। উদাহরণ:
@PreAuthorize("hasAuthority('READ_PRIVILEGE')") public void readData() { // নির্দিষ্ট প্রিভিলেজ যাচাই }
4. Time-Based Authorization:
- নির্দিষ্ট সময়ের উপর ভিত্তি করে অ্যাক্সেস কন্ট্রোল করা হয়।
উদাহরণ:
@PreAuthorize("T(java.time.LocalTime).now().isBefore(T(java.time.LocalTime).parse('18:00'))") public String accessResource() { return "Resource accessible before 6 PM"; }
Authentication এবং Authorization এর পার্থক্য
| বিষয় | Authentication | Authorization |
|---|---|---|
| উদ্দেশ্য | ব্যবহারকারীর পরিচয় যাচাই করা। | ব্যবহারকারী কি অ্যাক্সেস করতে পারবে তা যাচাই। |
| কার্যপ্রণালী | ইউজারনেম, পাসওয়ার্ড, টোকেন যাচাই। | রোল, প্রিভিলেজ বা রিসোর্স যাচাই। |
| সময় | সর্বপ্রথম ঘটে। | Authentication সফল হলে ঘটে। |
| উদাহরণ | "আপনি কে?" | "আপনি এটা অ্যাক্সেস করতে পারেন?" |
Spring Security-তে Authorization এর গুরুত্বপূর্ণ টিপস
- Role Naming:
রোলের নাম সাধারণতROLE_দিয়ে শুরু হওয়া উচিত। উদাহরণ:ROLE_ADMIN,ROLE_USER। - Password Encoding:
পাসওয়ার্ড এনক্রিপ্ট করুন।BCryptPasswordEncoderব্যবহার করুন। - Secure Default Configuration:
ডিফল্ট কনফিগারেশন যতটা সম্ভব সুরক্ষিত রাখুন। - Method Level Security:
মেথড লেভেলে সিকিউরিটি প্রয়োগ করতে@EnableGlobalMethodSecurity(prePostEnabled = true)ব্যবহার করুন। Custom Access Denied Handler:
কাস্টম Access Denied Page তৈরি করুন।http.exceptionHandling() .accessDeniedPage("/access-denied");
Spring Security-এর Authorization এর মাধ্যমে আপনি আপনার অ্যাপ্লিকেশনকে আরো নিরাপদ করতে পারবেন। উপরোক্ত প্রকারভেদ এবং উদাহরণগুলো আপনাকে প্রয়োজন অনুযায়ী সঠিক পদ্ধতি নির্বাচন করতে সাহায্য করবে।
Spring Security-তে UserDetailsService ইন্টারফেসটি একটি কেন্দ্রীয় ভূমিকা পালন করে। এটি এমন একটি কনট্রাক্ট প্রদান করে যার মাধ্যমে Spring Security আপনার অ্যাপ্লিকেশনের ব্যবহারকারী ডেটা লোড করতে পারে। এটি সাধারণত ডেটাবেস থেকে ব্যবহারকারী তথ্য রিট্রিভ করতে ব্যবহৃত হয়।
UserDetailsService ইন্টারফেস
UserDetailsService Spring Security-এর একটি প্রধান ইন্টারফেস যা শুধুমাত্র একটি মেথড প্রদান করে:
UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;
- Parameter:
username: ব্যবহারকারীর নাম যা লগইন করার সময় সরবরাহ করা হয়।
- Return Type:
- এটি একটি
UserDetailsঅবজেক্ট রিটার্ন করে যা ব্যবহারকারীর তথ্য ধারণ করে।
- এটি একটি
- Exception:
- যদি ব্যবহারকারী পাওয়া না যায়, তাহলে এটি
UsernameNotFoundExceptionছুড়ে দেয়।
- যদি ব্যবহারকারী পাওয়া না যায়, তাহলে এটি
Custom UserDetails তৈরি
Spring Security ডিফল্টভাবে org.springframework.security.core.userdetails.User ক্লাসটি ব্যবহার করে। তবে, যদি আপনার অ্যাপ্লিকেশনের জন্য অতিরিক্ত ব্যবহারকারী তথ্য (যেমন phoneNumber, address) প্রয়োজন হয়, তাহলে আপনাকে একটি custom UserDetails ক্লাস তৈরি করতে হবে।
১. Custom UserDetails ক্লাস তৈরি করুন
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
public class CustomUserDetails implements UserDetails {
private String username;
private String password;
private boolean isEnabled;
private Collection<? extends GrantedAuthority> authorities;
private String phoneNumber; // Custom attribute
public CustomUserDetails(String username, String password, boolean isEnabled,
Collection<? extends GrantedAuthority> authorities,
String phoneNumber) {
this.username = username;
this.password = password;
this.isEnabled = isEnabled;
this.authorities = authorities;
this.phoneNumber = phoneNumber;
}
// Standard UserDetails methods
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return authorities;
}
@Override
public String getPassword() {
return password;
}
@Override
public String getUsername() {
return username;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return isEnabled;
}
// Custom getter
public String getPhoneNumber() {
return phoneNumber;
}
}
২. Custom UserDetailsService ইমপ্লিমেন্ট করুন
UserDetailsService ইন্টারফেসটি ইমপ্লিমেন্ট করুন এবং আপনার ডেটাবেস থেকে ব্যবহারকারী ডেটা লোড করার জন্য এটি কাস্টমাইজ করুন।
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import java.util.Collections;
@Service
public class CustomUserDetailsService implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// Replace this with your database query
if (!"testuser".equals(username)) {
throw new UsernameNotFoundException("User not found with username: " + username);
}
// Simulated user data
String password = "$2a$10$abc123..."; // BCrypt hashed password
boolean isEnabled = true;
String phoneNumber = "123-456-7890";
// Return custom UserDetails
return new CustomUserDetails(username, password, isEnabled, Collections.emptyList(), phoneNumber);
}
}
৩. Custom UserDetailsService Spring Security Configuration-এ যুক্ত করুন
Spring Security configuration ক্লাসে CustomUserDetailsService ইমপ্লিমেন্টেশন ইনজেক্ট করুন।
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
public class SecurityConfig {
private final CustomUserDetailsService userDetailsService;
public SecurityConfig(CustomUserDetailsService userDetailsService) {
this.userDetailsService = userDetailsService;
}
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin();
return http.build();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public AuthenticationManager authenticationManager(HttpSecurity http) throws Exception {
return http.getSharedObject(AuthenticationManagerBuilder.class)
.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder())
.and()
.build();
}
}
৪. Custom UserDetails Access করা
Spring Security-এর মাধ্যমে লগইন করার পরে, ব্যবহারকারীর ডেটা অ্যাক্সেস করতে Authentication অবজেক্ট ব্যবহার করুন।
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
public class UserService {
public void getCurrentUserDetails() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
CustomUserDetails userDetails = (CustomUserDetails) authentication.getPrincipal();
System.out.println("Username: " + userDetails.getUsername());
System.out.println("Phone Number: " + userDetails.getPhoneNumber());
}
}
উপসংহার
Spring Security-এর UserDetailsService ইন্টারফেস এবং Custom UserDetails ক্লাস ব্যবহার করে একটি highly customizable authentication ব্যবস্থা তৈরি করা যায়। ডেটাবেস থেকে ব্যবহারকারী তথ্য সংগ্রহ এবং লগইন প্রক্রিয়ার সময় ব্যবহারকারী যাচাই করার জন্য এই পদ্ধতি কার্যকর। Spring Security-এর সুবিধা ব্যবহার করে নিরাপত্তা ব্যবস্থা আরও শক্তিশালী করতে এই ধরণের কাস্টমাইজেশন অপরিহার্য।
Spring Security ব্যবহার করে Authentication এবং Authorization বাস্তবায়ন করার একটি সাধারণ উদাহরণ নিম্নে দেয়া হলো।
Authentication এবং Authorization বাস্তবায়নের ধাপসমূহ
1. প্রয়োজনীয় ডিপেন্ডেন্সি যোগ করা
Spring Boot ব্যবহার করলে spring-boot-starter-security ডিপেন্ডেন্সি যোগ করুন।
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
2. SecurityConfig ক্লাস তৈরি করা
@Configuration এবং @EnableWebSecurity এনোটেশন ব্যবহার করে একটি কনফিগারেশন ক্লাস তৈরি করুন, যেখানে Authentication এবং Authorization এর নিয়মাবলী সংজ্ঞায়িত করা হবে।
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN") // শুধুমাত্র ADMIN রোলের জন্য
.antMatchers("/user/**").hasRole("USER") // শুধুমাত্র USER রোলের জন্য
.antMatchers("/public/**").permitAll() // পাবলিক API সবার জন্য উন্মুক্ত
.anyRequest().authenticated() // অন্য যেকোনো অনুরোধ প্রমাণীকরণ প্রয়োজন
.and()
.formLogin() // ফর্ম ভিত্তিক লগইন সক্রিয়
.and()
.httpBasic(); // HTTP Basic Authentication সক্রিয়
return http.build();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
3. In-Memory Authentication সেটআপ
In-Memory Authentication ব্যবহার করে একটি সহজ ডেমো বাস্তবায়ন করা যায়।
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
@Configuration
public class UserConfig {
@Bean
public UserDetailsService userDetailsService(PasswordEncoder passwordEncoder) {
UserDetails admin = User.builder()
.username("admin")
.password(passwordEncoder.encode("admin123"))
.roles("ADMIN")
.build();
UserDetails user = User.builder()
.username("user")
.password(passwordEncoder.encode("user123"))
.roles("USER")
.build();
return new InMemoryUserDetailsManager(admin, user);
}
}
4. Controller তৈরি
এখন কিছু এন্ডপয়েন্ট তৈরি করা যাক, যেখানে বিভিন্ন রোল অনুযায়ী Authorization প্রয়োগ করা হবে।
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/")
public class AppController {
@GetMapping("/public")
public String publicEndpoint() {
return "This is a public endpoint. Everyone can access!";
}
@GetMapping("/user")
public String userEndpoint() {
return "This endpoint is for USERS only!";
}
@GetMapping("/admin")
public String adminEndpoint() {
return "This endpoint is for ADMINS only!";
}
}
উদাহরণের কাজের প্রক্রিয়া
- Public Endpoint:
/publicএন্ডপয়েন্টে অ্যাক্সেস করতে Authentication প্রয়োজন নেই। এটি সবাই দেখতে পারে।
- User Endpoint:
/userএন্ডপয়েন্টে শুধুUSERরোলের ইউজাররা অ্যাক্সেস করতে পারবে।
- Admin Endpoint:
/adminএন্ডপয়েন্টে শুধুADMINরোলের ইউজাররা অ্যাক্সেস করতে পারবে।
HTTP Basic Authentication দিয়ে পরীক্ষা করা
Spring Security এর HTTP Basic Authentication ব্যবহার করলে, নিচের মতো লগইন পপ-আপ আসবে যেখানে আপনি ইউজারনেম এবং পাসওয়ার্ড দিয়ে লগইন করতে পারবেন।
টেস্ট:
- URL:
http://localhost:8080/public
Response: "This is a public endpoint. Everyone can access!" - URL:
http://localhost:8080/user- Username:
user - Password:
user123
Response: "This endpoint is for USERS only!"
- Username:
- URL:
http://localhost:8080/admin- Username:
admin - Password:
admin123
Response: "This endpoint is for ADMINS only!"
- Username:
Database-Based Authentication
1. ডাটাবেস স্কিমা তৈরি:
users এবং authorities টেবিল তৈরি করুন।
CREATE TABLE users (
username VARCHAR(50) PRIMARY KEY,
password VARCHAR(100) NOT NULL,
enabled BOOLEAN NOT NULL
);
CREATE TABLE authorities (
username VARCHAR(50) NOT NULL,
authority VARCHAR(50) NOT NULL,
FOREIGN KEY (username) REFERENCES users(username)
);
2. ডেটা যোগ করুন:
INSERT INTO users (username, password, enabled) VALUES ('admin', '$2a$10$abcdefghijklmopqrstuvwxyz', true);
INSERT INTO authorities (username, authority) VALUES ('admin', 'ROLE_ADMIN');
3. Spring Security JDBC Configuration:
@Bean
public UserDetailsService userDetailsService(DataSource dataSource) {
JdbcUserDetailsManager userDetailsManager = new JdbcUserDetailsManager(dataSource);
userDetailsManager.setUsersByUsernameQuery("SELECT username, password, enabled FROM users WHERE username = ?");
userDetailsManager.setAuthoritiesByUsernameQuery("SELECT username, authority FROM authorities WHERE username = ?");
return userDetailsManager;
}
উপসংহার:
- Authentication: ব্যবহারকারীর পরিচয় যাচাই (ইউজারনেম ও পাসওয়ার্ড ভিত্তিক)।
- Authorization: যাচাই করা ব্যবহারকারী কোন রিসোর্স অ্যাক্সেস করতে পারে তা নির্ধারণ করা।
উপরের উদাহরণগুলো ব্যবহার করে আপনি Spring Security দিয়ে সহজেই Authentication এবং Authorization বাস্তবায়ন করতে পারবেন।
Read more